---
title: Native Automation 2.0 (native2)
---

<Info>
`native2` is available starting from Patrol version `3.6.0`.
</Info>

## What is `native2`?

`native2` was created to address fundamental limitations in the original native automation approach. The original native API was primarily designed for Android, and attempts to make a single `Selector` work across both
platforms proved problematic because **iOS and Android use different selector arguments** (eg. Android's `resourceName` vs iOS's `identifier`) and a single selector approach couldn't effectively handle the fundamental differences
between iOS and Android element identification. **`native2` provides platform-specific selectors that work with both Android and iOS, giving you more accurate selectors instead of one shared selector.**


### Before `native2`

```dart
// You were forced to use flaky text-based selectors that work on both platforms
await $.native.tap(Selector(textContains: 'Login'));
```

```dart
// Before: Sometimes you needed to use platform-specific if statements in your test code.
if (Platform.isAndroid) {
  await $.native.tap(Selector(resourceId: 'com.android.camera2:id/shutter_button'));
} else {
  await $.native.tap(Selector(text: 'Take Picture'));
}
```

### With `native2`

`native2` provides a single method call that works across both platforms:

```dart
// After: Single method call with platform-specific selectors
await $.native2.tap(
  NativeSelector(
    android: AndroidSelector(
      resourceName: 'com.android.camera2:id/shutter_button',
    ),
    ios: IOSSelector(label: 'Take Picture'),
  ),
);
```

### Text Input Operations

```dart
// Enter password in secure field
await $.native2.enterText(
  NativeSelector(
    android: AndroidSelector(
      contentDescription: 'Password',
    ),
    ios: IOSSelector(
      elementType: IOSElementType.secureTextField,
    ),
  ),
  text: 'secretpassword',
);
```

### More platform-specific attributes like elementType for iOS

```dart
// Find elements by instance (when multiple elements match)
await $.native2.tap(
  NativeSelector(
    android: AndroidSelector(
      className: 'android.widget.Button',
      instance: 2, // Third button (0-indexed)
    ),
    ios: IOSSelector(
      elementType: IOSElementType.button,
      instance: 2, // Third button (0-indexed)
    ),
  ),
);
```

### Specifying App ID (iOS)

When working with iOS, you may need to specify the `appId` parameter to interact with elements in specific applications. This is particularly useful when your test needs to interact with system apps like Safari, Settings, or other third-party applications.

<Info>
The `appId` parameter is used for iOS. On Android, it will be ignored.
</Info>

```dart
await $.native2.tap(
  appId: 'com.apple.mobilesafari',
  NativeSelector(
    ios: IOSSelector(elementType: IOSElementType.button, label: 'Open'),
  ),
);
```

<Info>
Remember that if you don't provide a platform-specific selector (iOS or Android) and run the command on that platform, the command will fail.
</Info>
